import { h, defineComponent, ref, onMounted, onBeforeUnmount } from 'vue'
import type { PropType } from 'vue'

export const Card = defineComponent({
  name: 'UiCard',
  props: { title: String },
  setup(props, { slots }) {
    return () => {
      const children: any[] = []
      if (props.title) {
        children.push(
          h('div', { class: 'px-4 py-2 border-b text-sm text-gray-600' }, props.title)
        )
      }
      children.push(
        h('div', { class: 'p-4' }, slots.default ? slots.default() : [])
      )
      return h('div', { class: 'rounded-card border shadow-card bg-white' }, children)
    }
  }
})

export const Button = defineComponent({
  name: 'UiButton',
  props: {
    variant: { type: String, default: 'primary' },
    size: { type: String, default: 'default' }
  },
  setup(props, { slots, attrs }) {
    const sizeClass = props.size === 'sm' ? 'h-8 px-2 text-xs' : 'h-9 px-3 text-sm'
    return () => {
      const cls = props.variant === 'danger'
        ? `${sizeClass} rounded-btn bg-danger text-white hover:bg-red-500`
        : props.variant === 'ghost'
          ? `${sizeClass} rounded-btn bg-white border hover:bg-gray-50`
          : props.variant === 'success'
            ? `${sizeClass} rounded-btn bg-green-600 text-white hover:bg-green-700`
            : `${sizeClass} rounded-btn bg-primary text-white hover:bg-blue-500`
      return h('button', { class: cls, ...attrs }, slots.default ? slots.default() : '按钮')
    }
  }
})

export const Input = defineComponent({
  name: 'UiInput',
  props: {
    label: String,
    placeholder: String,
    modelValue: [String, Number] as PropType<string | number>,
    // 自定义 v-model 修饰符支持（如 .number）
    modelModifiers: { type: Object as PropType<Record<string, boolean>>, default: () => ({}) }
  },
  emits: ['update:modelValue'],
  setup(props, { attrs, emit }) {
    return () => {
      const children = []
      if (props.label) {
        children.push(h('label', { class: 'text-xs text-gray-500 block mb-1' }, props.label))
      }
      children.push(
        h('input', {
          class: 'w-full h-10 border rounded-btn px-3',
          placeholder: props.placeholder,
          value: props.modelValue != null ? String(props.modelValue) : '',
          onInput: (e: any) => {
            const raw = (e.target as HTMLInputElement).value
            const isNumber = (props.modelModifiers && props.modelModifiers.number) || (attrs as any).type === 'number'
            if (isNumber) {
              // 空串归零，避免 NaN 污染
              const next = raw === '' ? 0 : Number(raw)
              emit('update:modelValue', next)
            } else {
              emit('update:modelValue', raw)
            }
          },
          ...attrs
        })
      )
      return h('div', {}, children)
    }
  }
})

export const Select = defineComponent({
  name: 'UiSelect',
  props: {
    label: String,
    options: { type: Array, default: () => [] },
    modelValue: String
  },
  emits: ['update:modelValue'],
  setup(props, { attrs, emit }) {
    return () => {
      const children = []
      if (props.label) {
        children.push(h('label', { class: 'text-xs text-gray-500 block mb-1' }, props.label))
      }
      const optionElements = (props.options as string[]).map(opt =>
        h('option', { value: opt }, opt)
      )
      children.push(
        h('select', {
          class: 'w-full h-10 border rounded-btn px-3',
          value: props.modelValue,
          onChange: (e: any) => emit('update:modelValue', e.target.value),
          ...attrs
        }, optionElements)
      )
      return h('div', {}, children)
    }
  }
})

export const Tag = defineComponent({
  name: 'UiTag',
  props: {
    text: { type: String, required: true },
    closable: { type: Boolean, default: false }
  },
  emits: ['close'],
  setup(props, { emit }) {
    return () => {
      const children = []
      children.push(h('span', {}, props.text))
      if (props.closable) {
        children.push(
          h('button', {
            class: 'ml-1 text-gray-400 hover:text-gray-600',
            onClick: () => emit('close')
          }, '×')
        )
      }
      return h('span', {
        class: 'inline-flex items-center px-2 py-1 bg-gray-100 text-xs rounded'
      }, children)
    }
  }
})

export const PaginationBar = defineComponent({
  name: 'UiPaginationBar',
  props: {
    current: { type: Number, default: 1 },
    total: { type: Number, default: 5 }
  },
  emits: ['change'],
  setup(props, { emit }) {
    return () => {
      const buttons = []
      
      // Previous button
      buttons.push(
        h('button', {
          class: 'px-3 py-1 border rounded hover:bg-gray-50',
          onClick: () => props.current > 1 && emit('change', props.current - 1)
        }, '«')
      )
      
      // Page numbers
      for (let i = 1; i <= props.total; i++) {
        buttons.push(
          h('button', {
            class: i === props.current 
              ? 'px-3 py-1 bg-primary text-white rounded'
              : 'px-3 py-1 border rounded hover:bg-gray-50',
            onClick: () => emit('change', i)
          }, i.toString())
        )
      }
      
      // Next button
      buttons.push(
        h('button', {
          class: 'px-3 py-1 border rounded hover:bg-gray-50',
          onClick: () => props.current < props.total && emit('change', props.current + 1)
        }, '»')
      )
      
      return h('div', { class: 'flex justify-center gap-2 text-sm' }, buttons)
    }
  }
})

export const Dropdown = defineComponent({
  name: 'Dropdown',
  props: {
    items: {
      type: Array as PropType<Array<{
        label: string;
        value: string;
        icon?: string;
        variant?: 'default' | 'danger';
        disabled?: boolean;
      }>>,
      required: true
    },
    trigger: {
      type: String,
      default: '更多'
    },
    placement: {
      type: String as PropType<'left' | 'right'>,
      default: 'right'
    }
  },
  emits: ['select'],
  setup(props, { emit }) {
    const showMenu = ref(false)
    const dropdownRef = ref<HTMLElement>()

    const toggleMenu = (e: Event) => {
      e.stopPropagation()
      showMenu.value = !showMenu.value
    }

    const selectItem = (item: any) => {
      if (item.disabled) return
      emit('select', item.value)
      showMenu.value = false
    }

    const closeMenu = () => {
      showMenu.value = false
    }

    const handleClickOutside = (e: Event) => {
      if (dropdownRef.value && !dropdownRef.value.contains(e.target as Node)) {
        closeMenu()
      }
    }

    onMounted(() => {
      window.addEventListener('click', handleClickOutside)
    })

    onBeforeUnmount(() => {
      window.removeEventListener('click', handleClickOutside)
    })

    return () => {
      const triggerBtn = h('button', { class: 'h-9 px-2 rounded-btn border hover:bg-gray-50', onClick: toggleMenu }, props.trigger)

      const menuItems = (props.items as any[]).map(item =>
        h('button', {
          class: `flex items-center w-full text-left px-3 py-2 text-sm hover:bg-gray-50 ${item.variant === 'danger' ? 'text-danger' : ''} ${item.disabled ? 'opacity-50 cursor-not-allowed' : ''}`,
          onClick: () => selectItem(item)
        }, item.label)
      )

      const menu = showMenu.value
        ? h('div', {
            class: `absolute mt-1 w-40 rounded-card border shadow-card bg-white z-50 ${props.placement === 'right' ? 'right-0' : 'left-0'}`,
          }, menuItems)
        : null

      return h('div', { class: 'relative inline-block', ref: (el: any) => (dropdownRef.value = el) }, [triggerBtn, menu])
    }
  }
})